#!/usr/bin/env guile
!#

(use-modules (charting) (charting csv) (ice-9 match)
             ((ice-9 rdelim) #:select (read-line))
             ((srfi srfi-1) #:select (filter-map append-map)))

(define (parse-scenario data)
  (let lp ((in data) (out '()))
    (if (null? in)
        (filter-map string->number out)
        (lp (cdr in) (append (vector->list (car in)) out)))))

(define numeric-chars char-set:digit)

(define (scenario-name file)
  (let* ((end (or (string-index-right file numeric-chars)
                  (error "not numeric" file)))
         (start (or (string-index-right file (char-set-complement numeric-chars) 0 end) -1)))
    (string->number (substring file (1+ start) (1+ end)))))

(define (read-scenario file)
  (let ((rows (csv-port->row-list (open-input-file file) #\tab)))
    (or (= (vector-length (car rows)) 1)
        (error "expected only one row"))
    (cons (scenario-name file) (parse-scenario (cdr rows)))))

(define (read-annotations file)
  (with-input-from-file file
    (lambda ()
      (let lp ((annotations '()))
        (let ((line (read-line)))
          (if (eof-object? line)
              (reverse annotations)
              (lp (cons (* (floor-remainder (string->number (substring line 0 (string-index line #\space))) 1.0) 1000)
                        annotations))))))))

(define (main args)
  (match args
    ((title output annotations file file* ...)
     (unless (string-suffix? ".png" output)
       ;; Otherwise we would have the possibility of overwriting data.
       ;; That would be bad!
       (format (current-error-port)
               "Error: output name does not end with .png: ~a\n" output)
       (exit 1))
     (make-performance-series title (map read-scenario (cons file file*))
                              #:annotations (read-annotations annotations)
                              #:write-to-png output))
    (_
     (format (current-error-port)
             "Usage: perf-series.scm title output annotations file1 file2 ...

The files are expected to be in CSV format, with one row of headers,
and one row per run.  The different file names identify the different
scenarios that you want to compare.
")
     (exit 1))))

(main (cdr (command-line)))
